package br.com.rglariguet.pioneer.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import br.com.rglariguet.pioneer.dao.DadosBasicosProdutoDAO;
import br.com.rglariguet.pioneer.dao.DefeitoDAO;
import br.com.rglariguet.pioneer.dao.DefeitoPioneerDAO;
import br.com.rglariguet.pioneer.dao.ProdutoDAO;
import br.com.rglariguet.pioneer.dao.ReparoOemDAO;
import br.com.rglariguet.pioneer.dao.VeiculoDAO;
import br.com.rglariguet.pioneer.enums.StatusReparoOemEnum;
import br.com.rglariguet.pioneer.filtropesquisa.FiltroReparoOem;
import br.com.rglariguet.pioneer.modelos.DadosBasicosProduto;
import br.com.rglariguet.pioneer.modelos.Defeito;
import br.com.rglariguet.pioneer.modelos.DefeitoPioneer;
import br.com.rglariguet.pioneer.modelos.DetalheDefeitoDoReparoOem;
import br.com.rglariguet.pioneer.modelos.ReparoOem;
import br.com.rglariguet.pioneer.modelos.Veiculo;
import br.com.rglariguet.pioneer.util.MensagemTela;
import br.com.rglariguet.pioneer.wrapper.ListaReparoOemWrapper;

import com.google.gson.Gson;

@Controller
@RequestMapping("/seguro/oem/")
public class OemController extends ControllerComum{

	@Autowired
	private DadosBasicosProdutoDAO dadosBasicosProdutoDao;

	@Autowired
	private ProdutoDAO produtoDao;

	@Autowired
	private DefeitoPioneerDAO defeitoPioneerDao;

	@Autowired
	private DefeitoDAO defeitoDao;
	
	@Autowired
	private ReparoOemDAO reparoOemDao;

	@Autowired
	private VeiculoDAO veiculoDao;
	
	private ReparoOem reparoOem = new ReparoOem();
	
	private List<DefeitoPioneer> listaDeDefeitoPioneer = new ArrayList<DefeitoPioneer>();

	
	@RequestMapping("consultaReparosOEM")
	public ModelAndView abreTelaConsultaReparosOEM(ListaReparoOemWrapper reparoOemWrapper, boolean isRetornoConsulta){
		ModelAndView mv = new ModelAndView("/seguro/oem/consultaReparosOEM");
		mv.addObject("dadosBasicos", dadosBasicosProdutoDao.listarTodos());
		mv.addObject("reparoOem", reparoOemWrapper.getReparosOem());
		mv.addObject("status", Arrays.asList(StatusReparoOemEnum.values()));
		if (!isRetornoConsulta) {
			mv.addObject("filtroReparoOem", new FiltroReparoOem());
		} else {
			if (reparoOemWrapper.getReparosOem().isEmpty()) {
				mv.addObject("msg", criaMsgErro("reparo.nao.encontrado"));
			}
		}
		return mv;
	}
	
	private ModelAndView abreTelaLimpraEntradaDeReparo(MensagemTela msg) {
		return abreTelaEntradaDeReparo(msg, false,null);
	}

	
	@RequestMapping("entradaDeReparoOEM")
	public ModelAndView abreTelaEntradaDeReparo(MensagemTela msg,
			boolean isRetornoValidacao,ReparoOem reparoOem) {
		ModelAndView mv = new ModelAndView("/seguro/oem/entradaDeReparoOEM");
		mv.addObject("dadosBasicos", dadosBasicosProdutoDao.listarTodos());
		mv.addObject("msg", msg.getTipoMensagem() != null ? msg : null);
		
		
		if(msg.getTipoMensagem() != null){
			mv.addObject("statusToggle","aberto");
		}
		
		if (reparoOem != null) {
				populaListaDefeitoPionnerAutoComplete();
				mv.addObject("statusToggle","fechado");
				mv.addObject("reparoOem", reparoOem);
		}

		if (!isRetornoValidacao) {
			mv.addObject("statusToggle","aberto");
			mv.addObject("reparoOem", new ReparoOem());
			getReparoOem().setDetalheDefeitoDoReparoOem(new DetalheDefeitoDoReparoOem());
		}

		return mv;
	}
	
	@RequestMapping("buscarReparos")
	public ModelAndView consultar(FiltroReparoOem filtroReparoOem) {
		ListaReparoOemWrapper reparoOemWrapper = new ListaReparoOemWrapper();
		reparoOemWrapper.setReparosOem(reparoOemDao.listarComFiltro(filtroReparoOem));
		return abreTelaConsultaReparosOEM(reparoOemWrapper, true);
	}

	@RequestMapping("incluirReparo")
	public ModelAndView salvar(@Valid ReparoOem reparoOem, BindingResult br, HttpSession session) {
		
		if (!br.hasErrors()) {
			reparoOem.setNomeCriadorReparo((String)session.getAttribute("usuarioLogado"));
			Veiculo vei = veiculoDao.salvar(reparoOem.getVeiculo());
			reparoOem.setVeiculo(vei);
			salvaReparo(reparoOem);
			return abreTelaLimpraEntradaDeReparo(criaMsgSucesso("reparo.salvo.sucesso"));
		}
		return abreTelaEntradaDeReparo(criaMsgErro("reparo.salvo.erro"), true,null);
	}
	
	
	@RequestMapping("editarReparo")
	public ModelAndView abreTelaEdicaoReparo(long id) {
		setReparoOem(reparoOemDao.buscaPorId(id));
		return abreTelaEntradaDeReparo(new MensagemTela(), true, getReparoOem());
	}
	
	
	private void salvaReparo(ReparoOem reparoOem) {
		ReparoOem rep = reparoOemDao.buscaPorId(reparoOem.getId());
		
		DadosBasicosProduto dadosBasicosDoModeloSelecionado = dadosBasicosProdutoDao
				.buscaPorModelo(reparoOem.getProduto().getDadosBasicos()
						.getModelo());
		
		reparoOem.setDetalheDefeitoDoReparoOem(getReparoOem().getDetalheDefeitoDoReparoOem());

		for (Defeito defeito : reparoOem.getDetalheDefeitoDoReparoOem().getDetalheDefeitos()) {
			if(defeitoDao.buscaPorId(defeito.getId()) == null){
				defeitoDao.salvar(defeito);
			}else
				defeitoDao.merge(defeito);
		}
		
		reparoOem.getProduto().setDadosBasicos(dadosBasicosDoModeloSelecionado);

		if(rep == null){
			produtoDao.salvar(reparoOem.getProduto());
		}else
			produtoDao.merge(reparoOem.getProduto());
			
		reparoOem.setStatus(StatusReparoOemEnum.AGUARDANDO_APROVACAO);
		reparoOem.setDataDeCriacao(Calendar.getInstance());
		
		if(rep == null){
			reparoOemDao.salvar(reparoOem);
		}else
			reparoOemDao.merge(reparoOem);
	}
	
	private void populaListaDefeitoPionnerAutoComplete() {
		if (listaDeDefeitoPioneer.isEmpty()) {
			for (DefeitoPioneer defeitoPionner : defeitoPioneerDao.listarTodos()) {
				listaDeDefeitoPioneer.add(defeitoPionner);
			}
		}
	}
	
	@RequestMapping(value = "getFuncoes", method = RequestMethod.GET)
	public @ResponseBody List<DefeitoPioneer> getFuncoes(@RequestParam String nome) {
		return simulaBuscaAutocomplete(nome,"FUNC");
	}

	@RequestMapping(value = "getSintomas", method = RequestMethod.GET)
	public @ResponseBody List<DefeitoPioneer> getSintomas(@RequestParam String nome) {
		return simulaBuscaAutocomplete(nome,"SINT");
	}
	
	@RequestMapping("adicionaDefeitoAoReparo")
	public @ResponseBody String adicionaDefeitoAoReparo(@Valid Defeito defeito, BindingResult br,Model model) {

        if (defeito.getFuncao().isEmpty() && defeito.getSintoma().isEmpty() ) {
	            return "ERRO_VAZIO";
        }
		
        DefeitoPioneer sintomaRetornado = defeitoPioneerDao.buscaPorSintoma(defeito.getSintoma());
        DefeitoPioneer funcaoRetornado = defeitoPioneerDao.buscaPorFuncao(defeito.getFuncao());

        if (sintomaRetornado == null && funcaoRetornado == null) {
            return "ERRO_SINTOMA_FUNCAO";
        }else
       
        if (sintomaRetornado == null) {
            return "ERRO_SINTOMA";
        }else
        
        if (funcaoRetornado == null) {
            return "ERRO_FUNCAO";
        }

        
        getReparoOem().getDetalheDefeitoDoReparoOem().getDetalheDefeitos().add(defeito);
        return new Gson().toJson(defeito);
	}
	
//	@RequestMapping("excluirDefeito")
//	public @ResponseBody void excluiDefeito(int index, HttpServletResponse resp) {
//		if (getReparoOem().getDetalheDefeitoDoReparoOem().getDetalheDefeitos().size() > index) {
//			getReparoOem().getDetalheDefeitoDoReparoOem().getDetalheDefeitos().remove(index);
//		}
//		resp.setStatus(200);
//	}

	
	@RequestMapping("excluirDefeito")
	public @ResponseBody void excluiDefeito(DefeitoPioneer defeitoPioneer, HttpServletResponse resp) {
		for (int i = 0; i< getReparoOem().getDetalheDefeitoDoReparoOem().getDetalheDefeitos().size(); i++) {
			Defeito defeito = getReparoOem().getDetalheDefeitoDoReparoOem().getDetalheDefeitos().get(i);
			if (defeito.getSintoma().equals(defeitoPioneer.getSintoma())
					&& defeito.getFuncao().equals(defeitoPioneer.getFuncao())) {
				
				getReparoOem().getDetalheDefeitoDoReparoOem().getDetalheDefeitos().remove(i);
				break;
				
			}
		}
		resp.setStatus(200);
	}

	
	
	private List<DefeitoPioneer> simulaBuscaAutocomplete(String nome,String tipoAutoComplete) {
		List<DefeitoPioneer> result = new ArrayList<DefeitoPioneer>();
		for (DefeitoPioneer defeitoPionner : listaDeDefeitoPioneer) {
			if(tipoAutoComplete.equals("FUNC")){
				if (defeitoPionner.getCodigoFuncao().toLowerCase().contains(nome.toLowerCase()) || defeitoPionner.getFuncao().toLowerCase().contains(nome.toLowerCase()))
					result.add(defeitoPionner);
			}else{
				if (defeitoPionner.getCodigoSintoma().toLowerCase().contains(nome.toLowerCase()) || defeitoPionner.getSintoma().toLowerCase().contains(nome.toLowerCase()))
					result.add(defeitoPionner);
			}
		}
		return result;
	}

	@ModelAttribute("reparoOem")
	public ReparoOem getReparoOem() {
		return this.reparoOem;
	}

	public void setReparoOem(ReparoOem reparoOem) {
		this.reparoOem = reparoOem;
	}
}
